package com.license.logic.behaviorlog;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import com.license.common.excellParser.ReadExcel;



public class RiskCalculation {

	private static List<Double> arrays1;
	private static List<Double> arrays2;
	
	private static List<Double> alphas;
	private static List<Double> betas;
	
	private static double alpha;
	private static double beta;
	
	private double alphaScore;
	private double betaScore;
	
	public RiskCalculation() throws IOException{
		
	}
	
	public static void initiateConstants() throws IOException{
		if (arrays1 == null || arrays2 == null || alphas == null || betas == null){
			ReadExcel readExcel = new ReadExcel();
			arrays1 = readExcel.readAllColumnValues(4);
			arrays2 = readExcel.readAllColumnValues(9);
			alphas = readExcel.readColumnValues(17, 1, 8);
			betas = readExcel.readColumnValues(19, 1, 8);
			alpha = readExcel.readValue(22, 1);
			beta = readExcel.readValue(23, 1);
		}
	}
	
	public List<Double> findRiskValuesFromFiles(List<String> filesPath) throws DOMException, SAXException, IOException, ParserConfigurationException, ParseException{
		List<Double> riskValues = new ArrayList<Double>();
		for (String path : filesPath){
			riskValues.add(getRiskValue(path));
		}
		return riskValues;
	}
	
	public RiskFactor getRiskFactorsFromLog(String filePath) throws ParserConfigurationException, SAXException, IOException{
		RiskFactor riskFactor = new RiskFactor();
		
		File fXmlFile = new File(filePath);
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(fXmlFile);
		doc.getDocumentElement().normalize();
		
		riskFactor.setSex(((Element)doc.getElementsByTagName("sex").item(0)).getTextContent());
		riskFactor.setSmoker("true".equals(((Element)doc.getElementsByTagName("smoker").item(0)).getTextContent()));
		riskFactor.setSbp(Double.parseDouble(((Element)doc.getElementsByTagName("sbp").item(0)).getTextContent()));
		riskFactor.setHeight(Double.parseDouble(((Element)doc.getElementsByTagName("height").item(0)).getTextContent()));
		riskFactor.setWeight(Double.parseDouble(((Element)doc.getElementsByTagName("weight").item(0)).getTextContent()));
		riskFactor.setDiabetes("true".equals(((Element)doc.getElementsByTagName("diabetes").item(0)).getTextContent()));
		riskFactor.setFamilyCardHistory("true".equals(((Element)doc.getElementsByTagName("familyCardHistory").item(0)).getTextContent()));
		RiskFactorAdditional additional = new RiskFactorAdditional();
		additional.setAge(Integer.parseInt(((Element)doc.getElementsByTagName("age").item(0)).getTextContent()));
		additional.setAcitivityKalory(Double.parseDouble(((Element)doc.getElementsByTagName("activityKalory").item(0)).getTextContent()));
		additional.setNutriotionKalory(Double.parseDouble(((Element)doc.getElementsByTagName("nutritionKalory").item(0)).getTextContent()));
		riskFactor.setAdditional(additional);
		
		return riskFactor;
	}
	
	public double getRiskValue (String filePath) throws DOMException, SAXException, IOException, ParserConfigurationException, ParseException{
		return this.riskCalculation(this.getRiskFactorsFromLog(filePath));
	}
	
	public double riskCalculation(RiskFactor riskFactor) throws SAXException, IOException, ParserConfigurationException, DOMException, ParseException{
		initiateConstants();
		double score = 0;
		
		Double alphaGender = "f".equals(riskFactor.getSex()) ? 0.0 : 1.0;
		Double alphaAge = Math.log(riskFactor.getAdditional().getAge());
		Double alphaSbp = Math.log(riskFactor.getSbp());
		Double alphaSmoke = riskFactor.isSmoker()? 1.0 : 0.0;
		Double alphaFamily = riskFactor.isFamilyCardHistory()? 1.0 : 0.0;
		Double alphaBmi = Math.log(riskFactor.getBmi());
		Double alphaDiabetes = riskFactor.isDiabetes()? 1.0 : 0.0;
		List <Double> list = Arrays.asList(new Double[]{alphaGender,
				alphaAge, alphaSbp, alphaSmoke, alphaFamily,
				alphaBmi,alphaDiabetes });
		
		this.alphaScore = 0;
		this.betaScore = 0;
		
		for (int index = 0 ; index < list.size(); index++){
			this.alphaScore += list.get(index) * alphas.get(index);
			this.betaScore += list.get(index) * betas.get(index);
		}
		
		this.alphaScore = Math.exp(this.alphaScore - alpha);
		this.betaScore = Math.exp(this.betaScore - beta);
		
		for (int i = 0 ; i < arrays1.size()-2 ; i++){
			score += Math.log(arrays1.get(i)/ arrays1.get(i+1))
					* Math.pow(arrays1.get(i), this.alphaScore)
					* Math.pow(arrays2.get(i), this.betaScore) * alphaScore;
		}
		
		return score *  100 ;
	}
}
